#pragma once

#include "fxcc/core/graph/opengl3/Shader.h"
#include "mustache.hpp"

namespace fxcc
{
    namespace graph
    {
        namespace opengl3
        {

            struct FXCC_API ComputeEffect
            {
                bool m_Available{0};

                std::shared_ptr<fxcc::graph::opengl3::Shader> m_Shader;

                std::string m_ComputeCode;

                ComputeEffect(const std::string &computeCode) : m_ComputeCode(computeCode)
                {

                    Load();
                };
                void Load()
                {
                    m_Available = Init();
                }
                void Begin()
                {
                    m_Shader->Use();
                }
                void End()
                {
                    m_Shader->UnUse();
                }
                bool Init()
                {
                    fxcc::graph::opengl3::ShaderDesc desc;
                    desc.m_ComputeCode = GetComputeCode();

                    m_Shader = std::make_shared<fxcc::graph::opengl3::Shader>(desc);

                    return true;
                }

                static void DispatchCompute(int x, int y, int z)
                {
                    glDispatchCompute(x, y, z);
                }
                static std::string GetVersionStr()
                {
                    return "#version 460 core";
                }
                std::string GetComputeCode()
                {
                    static const std::string tempStr = R"(

{{{version}}}

{{{computeCode}}}
)";
                    kainjow::mustache::mustache m1(
                        tempStr);

                    kainjow::mustache::data d1;
                    d1.set("version", GetVersionStr());
                    d1.set("computeCode", m_ComputeCode);

                    return m1.render(d1);
                }
            };
        }
    }
};
